package com.yanqu.road.server.gameplayer.module.season;

import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.season.SeasonRewardConfig;
import com.yanqu.road.entity.season.SeasonRewardData;
import com.yanqu.road.entity.enums.eSeasonRewardType;
import com.yanqu.road.entity.season.SeasonRewardKey;
import com.yanqu.road.logic.bussiness.activity.SeasonRewardBusiness;
import com.yanqu.road.pb.activity.SeasonRewardProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.season.SeasonRewardMgr;
import com.yanqu.road.server.pb.SeasonRewardPb;
import com.yanqu.road.server.protocol.ClientProtocol;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

public class SeasonRewardModule extends GeneralModule {
    public SeasonRewardModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        for (Map.Entry<Integer, Map<Integer, Map<Integer, Map<Integer, SeasonRewardData>>>> entry : seasonRewardMap.entrySet()) {
            int systemId = entry.getKey();
            if (!SystemOpenMgr.systemOpen(player, systemId)) {
                continue;
            }
            for (Map<Integer, Map<Integer, SeasonRewardData>> value2 : entry.getValue().values()) {
                for (Map<Integer, SeasonRewardData> value3 : value2.values()) {
                    for (SeasonRewardData data : value3.values()) {
                        if (data.isInsertOption()) {
                            SeasonRewardBusiness.addSeasonRewardData(data);
                        } else if (data.isUpdateOption()) {
                            SeasonRewardBusiness.updateSeasonRewardData(data);
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public void afterLogin() {
        reloadConfigAndData();
    }

    // -----------------------------------------------------------------------

    // 赛季奖励数据        key：系统ID，赛季ID，奖励类型，奖励ID
    private Map<Integer, Map<Integer, Map<Integer, Map<Integer, SeasonRewardData>>>> seasonRewardMap = new ConcurrentHashMap<>();

    // 获取某种类型的数据
    public Map<Integer, SeasonRewardData> getSeasonRewardDataMap(int systemId, int seasonId, eSeasonRewardType type) {
        Map<Integer, Map<Integer, Map<Integer, SeasonRewardData>>> seasonMap = seasonRewardMap.get(systemId);
        if (seasonMap == null) {
            return new HashMap<>();
        }

        Map<Integer, Map<Integer, SeasonRewardData>> typeMap = seasonMap.get(seasonId);
        if (typeMap == null) {
            return new HashMap<>();
        }

        Map<Integer, SeasonRewardData> idMap = typeMap.get(type.getIntValue());
        if (idMap == null) {
            return new HashMap<>();
        }

        return idMap;
    }

    private synchronized void initUserData(Map<Integer, Map<Integer, Map<Integer, Map<Integer, SeasonRewardConfig>>>> configMap) {
        // 系统ID
        for (Map.Entry<Integer, Map<Integer, Map<Integer, Map<Integer, SeasonRewardConfig>>>> systemEntry : configMap.entrySet()) {
            int systemId = systemEntry.getKey();
            seasonRewardMap.putIfAbsent(systemId, new ConcurrentHashMap<>());
            Map<Integer, Map<Integer, Map<Integer, SeasonRewardData>>> seasonMap = seasonRewardMap.get(systemId);

            // 赛季ID
            for (Map.Entry<Integer, Map<Integer, Map<Integer, SeasonRewardConfig>>> seasonEntry : systemEntry.getValue().entrySet()) {
                int seasonId = seasonEntry.getKey();
                if (!seasonMap.containsKey(seasonId)) {
                    Map<Integer, Map<Integer, SeasonRewardData>> dataFromDb = SeasonRewardBusiness.getSeasonRewardDataMap(getUserId(), systemId, seasonId);
                    seasonMap.put(seasonId, dataFromDb);
                }
                Map<Integer, Map<Integer, SeasonRewardData>> typeMap = seasonMap.get(seasonId);

                // 奖励类型
                for (Map.Entry<Integer, Map<Integer, SeasonRewardConfig>> typeEntry : seasonEntry.getValue().entrySet()) {
                    int type = typeEntry.getKey();
                    Map<Integer, SeasonRewardConfig> idConfigMap = typeEntry.getValue();
                    eSeasonRewardType typeEnum = eSeasonRewardType.getType(type);
                    if (idConfigMap.isEmpty() || typeEnum == null) {
                        continue;
                    }
                    typeMap.putIfAbsent(type, new ConcurrentHashMap<>());
                    Map<Integer, SeasonRewardData> idMap = typeMap.get(type);

                    // 奖励ID
                    if (typeEnum.isRankType()) {
                        int minId = idConfigMap.values().stream().mapToInt(SeasonRewardConfig::getRewardId).min().getAsInt();
                        if (!idMap.containsKey(minId)) {
                            SeasonRewardData data = new SeasonRewardData(getUserId(), systemId, seasonId, type, minId);
                            data.setInsertOption();
                            idMap.put(minId, data);
                        }
                    } else {
                        for (SeasonRewardConfig config : idConfigMap.values()) {
                            if (!idMap.containsKey(config.getRewardId())) {
                                SeasonRewardData data = new SeasonRewardData(getUserId(), systemId, seasonId, type, config.getRewardId());
                                data.setInsertOption();
                                idMap.put(config.getRewardId(), data);
                            }
                        }
                    }
                }
            }
        }
    }

    public void reloadConfigAndData() {
        // 拿正在进行的配置
        Map<Integer, Map<Integer, Map<Integer, Map<Integer, SeasonRewardConfig>>>> tmpInTimeConfigMap = SeasonRewardMgr.getInTimeConfigMap();

        // 系统解锁判断
        Map<Integer, Map<Integer, Map<Integer, Map<Integer, SeasonRewardConfig>>>> inTimeConfigMap = new ConcurrentHashMap<>();
        for (Map.Entry<Integer, Map<Integer, Map<Integer, Map<Integer, SeasonRewardConfig>>>> entry : tmpInTimeConfigMap.entrySet()) {
            if (SystemOpenMgr.systemOpen(player, entry.getKey())) {
                inTimeConfigMap.put(entry.getKey(), entry.getValue());
            }
        }

        // 初始化数据
        initUserData(inTimeConfigMap);
        // 同步全部配置
        SeasonRewardProto.SeasonRewardSyncConfigRespMsg.Builder configRespMsg = SeasonRewardPb.parseSeasonRewardSyncConfigRespMsg(inTimeConfigMap, player.getLanguage());
        player.sendPacket(ClientProtocol.U_SEASON_REWARD_SYNC_ALL_CONFIG, configRespMsg);
        // 同步全部数据
        SeasonRewardProto.SeasonRewardSyncDataRespMsg.Builder dataRespMsg = SeasonRewardPb.parseSeasonRewardSyncDataRespMsg(inTimeConfigMap, seasonRewardMap);
        player.sendPacket(ClientProtocol.U_SEASON_REWARD_SYNC_ALL_DATA, dataRespMsg);
    }

    // -----------------------------------------------------------------------

    // 待同步数据
    private final Map<Integer, Map<Integer, Map<Integer, Map<Integer, SeasonRewardData>>>> syncMap = new ConcurrentHashMap<>();

    public void addChangeData(Map<Integer, SeasonRewardData> map) {
        synchronized (syncMap) {
            Optional<SeasonRewardData> first = map.values().stream().findFirst();
            if (!first.isPresent()) {
                return;
            }
            SeasonRewardData data = first.get();

            syncMap.putIfAbsent(data.getSystemId(), new HashMap<>());
            Map<Integer, Map<Integer, Map<Integer, SeasonRewardData>>> seasonMap = syncMap.get(data.getSystemId());
            seasonMap.putIfAbsent(data.getSeasonId(), new HashMap<>());
            Map<Integer, Map<Integer, SeasonRewardData>> typeMap = seasonMap.get(data.getSeasonId());
            typeMap.putIfAbsent(data.getType(), new HashMap<>());
            Map<Integer, SeasonRewardData> idMap = typeMap.get(data.getType());
            idMap.putAll(map);
        }
    }

    public void syncChangeData() {
        HashMap<Integer, Map<Integer, Map<Integer, Map<Integer, SeasonRewardData>>>> map;
        synchronized (syncMap) {
            if (syncMap.isEmpty()) {
                return;
            }
            map = new HashMap<>(syncMap);
            syncMap.clear();
        }

        // 同步
        SeasonRewardProto.SeasonRewardSyncDataRespMsg.Builder builder = SeasonRewardPb.parseSeasonRewardSyncDataRespMsg(map);
        player.sendPacket(ClientProtocol.U_SEASON_REWARD_SYNC_DATA, builder);
    }

}
